package com.ssy.lingxi.platform.template.service.serviceimpl.web;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.platform.template.service.constant.CommonBooleanEnum;
import com.ssy.lingxi.platform.template.service.constant.SeoDoorTypeEnum;
import com.ssy.lingxi.platform.template.service.entity.door.*;
import com.ssy.lingxi.platform.template.service.model.dto.common.CommonStatusDTO;
import com.ssy.lingxi.platform.template.service.model.dto.common.IdDTO;
import com.ssy.lingxi.platform.template.service.model.dto.web.SaveSeoDTO;
import com.ssy.lingxi.platform.template.service.model.qo.SeoQO;
import com.ssy.lingxi.platform.template.service.repository.*;
import com.ssy.lingxi.platform.template.service.service.web.SeoWebService;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author fhj
 * @version 2.0.0
 * @menu web - SEO - 业务实现层
 * @date 2021/04/14
 */
@Slf4j
@Service
public class SeoWebServiceImpl implements SeoWebService {

    @Resource
    private JPAQueryFactory jpaQueryFactory;
    @Resource
    private SeoRepository seoRepository;
    @Resource
    private MemberShopRepository memberShopRepository;
    @Resource
    private MemberChannelRepository memberChannelRepository;
    @Resource
    private MemberPurchaseRepository memberPurchaseRepository;
    @Resource
    private MemberSelfRepository memberSelfRepository;

    @Override
    @ApiOperation(value = "列表")
    public Wrapper<PageData<Seo>> page(SeoQO qo, UserLoginCacheDTO user) {
        //根据门户类型获取对应得门户ID
        Long doorId = getDoorId(qo.getDoorType(), user);
        if (doorId == null) {
            return Wrapper.fail(ResponseCode.PT_COULD_NOT_FIND_THE_CORRESPONDING_PORTAL_ID);
        }

        //查询表实体 - SEO
        QSeo seo = QSeo.seo;

        //查询条件构造 - 必要条件
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(seo.doorType.eq(qo.getDoorType()));
        predicates.and(seo.doorId.eq(doorId));

        //搜索条件
        if (StringUtils.isNotBlank(qo.getName())) {
            predicates.and(seo.name.like("%" + qo.getName() + "%"));
        }

        //查询
        JPAQuery<Seo> query = jpaQueryFactory.select(seo).from(seo).where(predicates);

        //总记录数
        long totalCount = query.fetchCount();

        //列表数据
        List<Seo> list = query.orderBy(seo.createTime.desc()).offset((long) (qo.getCurrent() - 1) * qo.getPageSize()).limit(qo.getPageSize()).fetch();

        return Wrapper.success(new PageData<>(totalCount, list));
    }

    @Override
    @ApiOperation(value = "详情")
    public Wrapper<Seo> get(IdDTO dto, UserLoginCacheDTO user) {
        Seo seo = seoRepository.findById(dto.getId()).orElse(null);
        if (seo == null) {
            throw new BusinessException(ResponseCode.PT_RECORDS_DON_T_EXIST);
        }
        return Wrapper.success(seo);
    }

    @Override
    @Transactional
    @ApiOperation(value = "新增")
    public Wrapper<Void> add(SaveSeoDTO dto, UserLoginCacheDTO user) {
        //根据门户类型获取对应得门户ID
        Long doorId = getDoorId(dto.getDoorType(), user);
        if (doorId == null) {
            return Wrapper.fail(ResponseCode.PT_COULD_NOT_FIND_THE_CORRESPONDING_PORTAL_ID);
        }
        //判断是否已存在相同的页面类型
        Integer doorType = dto.getDoorType();
        Integer type = dto.getType();
        System.out.println(type);
        List<Seo> seoList = seoRepository.findAllByDoorIdAndDoorTypeAndType(doorId, doorType, type);
        if (seoList.size() > 0) {
            return Wrapper.fail(ResponseCode.PT_PAGE_TYPE_ALREADY_EXISTS);
        }
        //新增
        Seo seo = new Seo();
        BeanUtils.copyProperties(dto, seo);
        seo.setDoorId(doorId);
        seoRepository.saveAndFlush(seo);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "修改")
    public Wrapper<Void> update(SaveSeoDTO dto, UserLoginCacheDTO user) {
        Seo seo = seoRepository.findById(dto.getId()).orElse(null);
        if (seo == null) {
            throw new BusinessException(ResponseCode.PT_RECORDS_DON_T_EXIST);
        }
        if (seo.getStatus().equals(CommonBooleanEnum.YES.getCode())) {
            throw new BusinessException(ResponseCode.PT_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        //判断是否已存在相同的页面类型
        List<Seo> seoList = seoRepository.findAllByDoorIdAndDoorTypeAndTypeAndIdNot(seo.getDoorId(), dto.getDoorType(), dto.getType(), dto.getId());
        if (seoList.size() > 0) {
            return Wrapper.fail(ResponseCode.PT_PAGE_TYPE_ALREADY_EXISTS);
        }
        seo.setType(dto.getType());
        seo.setName(dto.getName());
        seo.setLink(dto.getLink());
        seo.setTitle(dto.getTitle());
        seo.setDescription(dto.getDescription());
        seo.setKeywords(dto.getKeywords());
        seoRepository.saveAndFlush(seo);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "停用/启用")
    public Wrapper<Void> updateStatus(CommonStatusDTO dto, UserLoginCacheDTO user) {
        Seo seo = seoRepository.findById(dto.getId()).orElse(null);
        if (seo == null) {
            throw new BusinessException(ResponseCode.PT_RECORDS_DON_T_EXIST);
        }
        seo.setStatus(dto.getStatus());
        seoRepository.saveAndFlush(seo);
        return Wrapper.success();
    }

    @Override
    @Transactional
    @ApiOperation(value = "删除")
    public Wrapper<Void> delete(IdDTO dto, UserLoginCacheDTO user) {
        Seo seo = seoRepository.findById(dto.getId()).orElse(null);
        if (seo == null) {
            throw new BusinessException(ResponseCode.PT_RECORDS_DON_T_EXIST);
        }
        if (seo.getStatus().equals(CommonBooleanEnum.YES.getCode())) {
            throw new BusinessException(ResponseCode.PT_DATA_STATUS_INCORRECT_OPERATE_INVALID);
        }
        seoRepository.delete(seo);
        return Wrapper.success();
    }

    /**
     * 根据门户类型获取对应得门户ID
     *
     * @param doorType 门户类型：1-店铺门户  2-渠道门户  3-采购门户
     * @param user     当前登录用户
     */
    private Long getDoorId(Integer doorType, UserLoginCacheDTO user) {
        Long doorId = null;
        if (doorType.equals(SeoDoorTypeEnum.SHOP.getCode())) {
            MemberShop memberShop = memberShopRepository.findByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId());
            doorId = memberShop != null ? memberShop.getId() : doorId;
        }
        if (doorType.equals(SeoDoorTypeEnum.CHANNEL.getCode())) {
            MemberChannel memberChannel = memberChannelRepository.findByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId());
            doorId = memberChannel != null ? memberChannel.getId() : doorId;
        }
        if (doorType.equals(SeoDoorTypeEnum.PURCHASE.getCode())) {
            MemberPurchase memberPurchase = memberPurchaseRepository.findByMemberIdAndRoleId(user.getMemberId(), user.getMemberRoleId());
            doorId = memberPurchase != null ? memberPurchase.getId() : doorId;
        }
        if (doorType.equals(SeoDoorTypeEnum.SELF.getCode())) {
            MemberSelf memberSelf = memberSelfRepository.findByMemberId(user.getMemberId());
            doorId = memberSelf != null ? memberSelf.getId() : doorId;
        }
        return doorId;
    }
}
